package IceAssembly;

import Comp.*;

/**
 * A helper set of operations to help with processing all the instructions
 * and parameters managaebale and to better ensure accuracy and validity.
 */
public class SubProcess {
    
    Table table_instance = new Table();
    Check check_instance = new Check();
    Control control_instance = new Control();
    Convert convert_instance = new Convert();    
    
    /**
    * Provides the neccesary info for processing n-type parameters. This includes 
    * n, nn, nnn, nmax, and such.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * none yet
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param parameter_info The parameter type (n, nn, nnn, nmax)
    * @param parameter Parameter as operand
    * @return 0 - non int values, 1 - overflow, 2 - correct
    */   
    protected int processAlln(String parameter_info, String parameter){
        if(parameter.contentEquals("")) 
            return 0;
        Check check_instance = new Check();
        if(check_instance.isInt(parameter)==0){
            return 0;
        }else{
            if(check_instance.isParameterOverflow(parameter, parameter_info)==1){
                return 1;                    
            }
        }
        return 2;
    }
    
    /**
    * The processPseudoIntLiteral function will convert the integer provided into an appropriate binary representation.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param int_literal This is the literal that is being passed in to be converted to a binary representation.
    * @return As long as the function hasn't been provided an invalid literal, the binary representation will be returned.
    */
    protected String processPseudoIntLiteral(String int_literal){
        if(int_literal.charAt(0)=='+'){
            int_literal = int_literal.substring(1);
            if(check_instance.isInt(int_literal)==0){
                return "0";
            }
        }
        try{
            int temp = Integer.parseInt(int_literal);
            if(temp==-32768){
                return "1000000000000000";
            }else if(temp>=-32767 && temp<0){ 
                temp = temp*-1;
                return "1".concat(convert_instance.getBitCode(String.valueOf(temp),15));
            }else if(temp>=0 && temp<=32767){
                return convert_instance.getBitCode(String.valueOf(temp),16);
            }     
        }catch(NumberFormatException e){
            return "0";
        }
        return "0";
    }
    
    /**
    * The processPseudoCharLiteral operation will process a character literal from a Pseudo Operation and convert it to the appropriate binary representation.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 04-26-08 - Revised Documentation - Keith Hill<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param char_literal The literal value being processed by the operation.
    * @return The binary representation of the character literal is returned.  If the literal is invalid, the value of 0 is returned.
    */    
    protected String processPseudoCharLiteral(String char_literal){
        if(char_literal.contentEquals("''")){
            char_literal = "' '";
        }
        if(!(char_literal.length()==3 || char_literal.length()==4)){
            return "0";
        }
        if(!char_literal.startsWith("'") && !char_literal.endsWith("'")){
            return "0";
        }
        if(char_literal.length()==3){
            int character = char_literal.charAt(1);
            if(character >=0 && character <=255){
                return convert_instance.getBitCode(String.valueOf(character),16);
            }
            return "0";
        }
        if(char_literal.length()==4){
            int character = char_literal.charAt(1);
            int character2 = char_literal.charAt(2);
            if(character >=0 && character <=255){
                if(character2 >=0 && character2 <=255){
                    String temp1 = convert_instance.getBitCode(String.valueOf(character),8);
                    String temp2 = convert_instance.getBitCode(String.valueOf(character2),8);
                    return temp1.concat(temp2);
                }
            }
        }
        return "0";
    }
    
    /**
    * The processPseudoHexLiteral receives an incoming hex value included in a Pseudo Operation and converts it to binary.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 - Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param hex_literal This is the incoming value of Hex.  
    * @return The binary representation of the incoming Hex value is returned unless an invalid parameter is entered.
    */    
    protected String processPseudoHexLiteral(String hex_literal){
        if(hex_literal.length()>4){
            return "0";
        }
        if(hex_literal.contains("+") || hex_literal.contains("-")){
            return "0";
        }
        try{
            return convert_instance.getBitCode(String.valueOf(Integer.parseInt(hex_literal,16)),16);
        }catch(NumberFormatException e){
            return "0";
        }
    }
      
    /**
    * The processPseudoBinaryLiteral operation takes an incoming literal from a Pseudo Operation and returns the appropriate binary representation.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param binary_literal This is the incoming value in binary representation.
    * @return Unless an invalid character is included in the literal, the binary representation in the appropriate format is returned.
    */    
    protected String processPseudoBinaryLiteral(String binary_literal){
        if(binary_literal.length()>16){
            return "0";
        }
        if(binary_literal.contains("-") || binary_literal.contains("+")){
            return "0";
        }
        try{
            return convert_instance.getBitCode(String.valueOf(Integer.parseInt(binary_literal,2)),16);
        }catch(NumberFormatException e){
            return "0";
        }
    }
    
    /**
    * The processPseudoLiterals operation determines which type of literal is being passed.  Once it is determined, 
     * the appropriate function is call.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 04-26-08 - Revised Documentation - Keith Hill<br>
    * 05-11-08 - Error Condition 211 removed - Not Needed. - Yogesh Jindal<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param literal This is the literal being passed in for processing.
    * @return This function returns the result from the function that is called once the type of literal is determined.
    */    
    protected String processPseudoLiterals(String literal){        
        if(literal.length()<3){
            return "0";
        }        
        literal = literal.replace(" =", "="); literal = literal.replace("= ", "=");
        literal = literal.replace(" '", "'"); literal = literal.replace("' ", "'");
        
        int status=0;        
        if(literal.substring(0,2).toUpperCase().compareTo("I=")==0){
            status=1;
        }else if(literal.substring(0,2).toUpperCase().compareTo("C=")==0){
            status=2;
        }else if(literal.substring(0,2).toUpperCase().compareTo("X=")==0){
            status=3;
        }else if(literal.substring(0,2).toUpperCase().compareTo("B=")==0){
            status=4;
        }else{
            return "0";  
        }
        
        switch(status){
            case 1: return processPseudoIntLiteral(literal.substring(2));
            case 2: return processPseudoCharLiteral(literal.substring(2));
            case 3: return processPseudoHexLiteral(literal.substring(2));
            case 4: return processPseudoBinaryLiteral(literal.substring(2));
        }
        return "0" ;
    }
    
    /**
    * The processMnemonicIntLiteral function processes an Integer literal and returns the binary representation.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param int_literal This is the integer literal being processed.
    * @return Unless the function has been passed an invalid literal, we return the appropriate binary representation.
    */    
    protected String processMnemonicIntLiteral(String int_literal){
        if(int_literal.charAt(0)=='+'){
            int_literal = int_literal.substring(1);
            if(check_instance.isInt(int_literal)==0){
                return "0";
            }
        }        
        try{
            int temp = Integer.parseInt(int_literal);        
            if(temp==-512){
                return "1000000000";
            }else if(temp>=-511 && temp<0){                
                temp = temp*-1;
                return "1".concat(convert_instance.getBitCode(String.valueOf(temp),9));
            }else if(temp>=0 && temp<=511){
                return convert_instance.getBitCode(String.valueOf(temp),10);
            }
        }catch(NumberFormatException e){
            return "0";
        }
        return "0";
    }

    /**
    * The processMnemonicCharLiteral produces the appropriate binary representation of the parameter and returns it.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 - Revised Documentation - Keith Hill<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param char_literal This is the literal character that needs to be processed and converted to binary.
    * @return Unless we have been provided an invalid literal parameter, the binary representation will be returned.
    */    
    protected String processMnemonicCharLiteral(String char_literal){
        if(char_literal.contentEquals("''")){
            char_literal = "' '";
        }
        if(char_literal.length()!=3){
            return "0";
        }
        if(!char_literal.startsWith("'") && !char_literal.endsWith("'")){
            return "0";
        }
        int character = char_literal.charAt(1);
        if(character>=0 && character<=255){
            return "00".concat(convert_instance.getBitCode(String.valueOf(character),8));
        }
        return "0";
    }
    
    /**
    * The processMnemonicHexLiteral operation receives a Hex literal and produces the appropriate binary.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 - Revised Documentation - Keith Hill<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param hex_literal This is the incoming value that needs to be checked and converted.
    * @return Unless the function is provided an invalid parameter, the appropriate binary representation is produced.
    */    
    protected String processMnemonicHexLiteral(String hex_literal){
        if(hex_literal.length()>2){
            return "0";
        }
        if(hex_literal.contains("+") || hex_literal.contains("-")){
            return "0";
        }
        try{
            return convert_instance.getBitCode(String.valueOf(Integer.parseInt(hex_literal,16)),10);
        }catch(NumberFormatException e){
            return "0";
        }        
    }
    
    /**
    * The processMnemonicBinaryLiteral function processes the binary literal from a mnemonic operation and converts it to the appropriate 
    * binary representation needed.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param binary_literal This is the incoming value that needs to be converted.
    * @return Unless the function is provided with an invalid paramenter, the appropriate binary representation will be returned.
    */    
    protected String processMnemonicBinaryLiteral(String binary_literal){
        if(binary_literal.length()>10){
            return "0";
        }
        if(binary_literal.contains("-") || binary_literal.contains("+")){
            return "0";
        }
        try{
            return convert_instance.getBitCode(String.valueOf(Integer.parseInt(binary_literal,2)),10);
        }catch(NumberFormatException e){
            return "0";
        }        
    }
    
    /**
    * The processMnemonicLiterals function receives an incoming value and determines which type of literal it is.  Once that 
     * is determined, the appropriate helper function will be called to get the binary representation.  The results from that 
     *  helper function is then returned.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 04-26-08 - Revised Documentation - Keith Hill<br>
    * 05-11-08 - Error condition 211 removed - not needed - Yogesh Jindal.<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param literal This is the incoming value that needs to be converted to binary.
    * @return Unless an invalid parameter is entered, the binary representation of the literal parameter is returned.
    */
    protected String processMnemonicLiterals(String literal){        
        if(literal.length()<3){
            return "0";
        }        
        literal = literal.replace(" =", "="); literal = literal.replace("= ", "=");
        literal = literal.replace(" '", "'"); literal = literal.replace("' ", "'");
        
        int status=0;        
        if(literal.substring(0,2).toUpperCase().compareTo("I=")==0){
            status=1;
        }else if(literal.substring(0,2).toUpperCase().compareTo("C=")==0){
            status=2;
        }else if(literal.substring(0,2).toUpperCase().compareTo("X=")==0){
            status=3;
        }else if(literal.substring(0,2).toUpperCase().compareTo("B=")==0){
            status=4;
        }else{
            return "0";  
        }
        
        switch(status){
            case 1: return processMnemonicIntLiteral(literal.substring(2));
            case 2: return processMnemonicCharLiteral(literal.substring(2));
            case 3: return processMnemonicHexLiteral(literal.substring(2));
            case 4: return processMnemonicBinaryLiteral(literal.substring(2));
        }
        return "0" ;
    }

    /**
    * The processStart function checks for invalid uses of the start Pseudo Op.  If the line is 
     * 0, a start Pseudo Op must be entered.  If the line counter is not 0, the function will produce an error. 
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 - Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * 001 - Start not located and it was expected.<br>
    * 002 - Invalid use of start <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param tokened_string The array of strings will be passed for an appropriate check to be completed.
    * @return The function will return 50 if it was correct or it was fixed.  4000 will be returned if there is a problem with start on the first line.  1000 will be returned if the maximum number of errors has been exceeded.
    */    
    protected int processStart(String[] tokened_string){//111-error code        
        if(control_instance.line_num==0){
            if(tokened_string[2].toUpperCase().compareTo("START")==0){
                if(tokened_string[0].compareTo("1")==0){
                    if(processAlln("nmax", tokened_string[3])==2){
                        Control.location_counter=Integer.parseInt(tokened_string[3]);
                        table_instance.addToSymbolTable(tokened_string[1], "START", "-");//valid start                        
                        table_instance.start_index=Integer.parseInt(tokened_string[3]);
                        return 50;
                    }
                }
            }
            if(tokened_string[2].toUpperCase().compareTo("START")!=0){
                table_instance.addToErrorTable("001");//no start
                return 4000;
            }else{
                table_instance.addToErrorTable("002");//invalid start
                return 4000;
            }            
        }else{
            if(table_instance.addToErrorTable("111")==0){//start in middle of code
                return 1000;
            }
            return 50;
        }        
    }

    /**
    * The processEnd function will look for any errors if an end pseudo operation is used.  
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 - Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * 206 - An operand was found after the end pseudo operation was found. <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param tokened_string tokened_string The array of strings will be passed for an appropriate check to be completed.
    * @return The value of 1000 will be returned if the max number of errors has been reached.  5 will be returned if an end Pseudo Operation is detected.
    */    
    protected int processEnd(String[] tokened_string){
        String[] start_label = table_instance.getAllLabels("START");
        
        if(tokened_string[0].contentEquals("0")){
            if(tokened_string[3].contentEquals(start_label[1])){
                if(tokened_string[4].contentEquals(",")){//found operands after end label
                    if(table_instance.addToErrorTable("206")==0){
                        return 1000;
                    }
                }
                return 5;
            }
        }
        if(tokened_string[0].contentEquals("1")){
            if(table_instance.addToErrorTable("207")==0){//label ignored
                return 1000;
            }
        }
        if(!tokened_string[3].contentEquals(start_label[1])){
            if(table_instance.addToErrorTable("208")==0){//label replaced with start label
                return 1000;
            }
        }
        return 5;
    }
    
    /**
    * The processBinary5 function is called when the DUMP instruction has been received.  There are 
    * five possible operands that could be used.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 04-26-08 - Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param operand This is the operand that is to be tested for validity and converted to binary.
    * @return Unless the function is provided with an invalid operand, the appropriate binary representation will be produced.
    */    
    protected String processBinary5(String operand){
        String[] possibilities = {"1","2","4","8","15"};
        for(int index=0; index<possibilities.length; index++){
            if(operand.contentEquals(possibilities[index])){
                return convert_instance.getBitCode(operand,10);
            }
        }
        return "0";
    }

    /**
    * The processBinary4 function is called when the CLRS instruction has been received.  There are 
     * four possible operands that could be used.
    * <p>
    * <b>Change Log:</b><br>
    * 04-24-08 - Initial Code - Yogesh Jindal<br>
    * 04-26-08 - Revised Documentation - Peter Dietz<br>
    * 4-26-08 - Revised Documentation - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-24-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param operand This is the operand that is to be tested for validity and converted to binary.
    * @return Unless the function is provided with an invalid operand, the appropriate binary representation will be produced.
    */ 
    protected String processBinary4(String operand){
        String[] possibilities = {"1","2","4","8"};
        for(int index=0; index<possibilities.length; index++){
            if(operand.contentEquals(possibilities[index])){
                return convert_instance.getBitCode(operand,10);
            }
        }
        return "0";
    }
    
    /**
    * This function is called from process.java whenever one of the possibilities of Mnemonic
    * operand is a number.<p>
    * <b>Change Log:</b><br>
    * 04-27-08 - Initial Code - Yogesh Jindal<br>   
    * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 04-27-08
    * <p><b>Original Author:</b>  Yogesh Jindal
    * @param operand - operand to be processed as an integer.
    * @return 0 if not int else return 1000,2000,50 or the 11 bit binary code if the integer is within range.
    */
    protected String check_1(String operand){        
        if(check_instance.isInt(operand)!=1){
            return "0";
        }
        if(check_instance.isParameterOverflow(operand, "nmax")==1){
            if(table_instance.addToErrorTable("154")==0){
                return "1000";//fatal error more than 3072 errors
            }
            if(table_instance.addToIntermediateFile("11000", "00000000000", "A") == 0){
               return "2000";//fatal error more than 1024 memory words
            }
            return "50";
        }
        return convert_instance.getBitCode(operand, 11);        
    }
    
    /**
     * This function is called from process.java whenever one of the possibilities of Mnemonic
     * operand is a literal.<p>
     * <b>Change Log:</b><br>
     * 04-27-08 - Initial Code - Yogesh Jindal<br>
     * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
     * <p>
     * <b>Error Conditions Tested:</b><br>
     * <INSERT EACH CONDITION TESTED> <br>
     * <p>
     * <b>Date of module being installed:</b> 04-27-08
     * <p><b>Original Author:</b>  yogesh jindal
     * @param operand - The literal operand to be checked.
     * @return 0 if not a literal else return 1000 or 2000 or 50 depending upon the situation 
     * or the 11 bit binary code if the literal is correct and within range.
     */
    protected String check_2(String operand){
        if(check_instance.isLiteral(operand)==0){
            return "0";
        }
        String temp = processMnemonicLiterals(operand);
        if(temp.contentEquals("0")){
            if(table_instance.addToErrorTable("155")==0){
                return "1000";//fatal error more than 3072 errors
            }
            if(table_instance.addToIntermediateFile("11000", "00000000000", "A") == 0){
               return "2000";//fatal error more than 1024 memory words
            }
            return "50";
        }       
        return "1".concat(temp);        
    }
    
    /**
     * This function is called from process.java whenever one of the possibilities of Mnemonic
     * operand is a label or star notation.<p>
     * <b>Change Log:</b><br>
     * 04-27-08 - Initial Code - Yogesh Jindal<br>
     * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
     * <p>
     * <b>Error Conditions Tested:</b><br>
     * <INSERT EACH CONDITION TESTED> <br>
     * <p>
     * <b>Date of module being installed:</b> 04-27-08
     * <p><b>Original Author:</b>  yogesh jindal
     * @param op_code - the op_code for the function mnemonic pair.
     * @param operand - the operand to be checked for a label or star notation.
     * @return Returns 1000 or 2000 or 50 depending upon the situation 
     * or the 11 bit binary code if the Label or star notation is correct and within range.
     */
    protected int check_3(String op_code, String operand){
        operand = operand.replace(" *","*"); operand = operand.replace("* ","*");
        operand = operand.replace(" +","+"); operand = operand.replace("+ ","+");
        operand = operand.replace(" -","-"); operand = operand.replace("- ","-");
        if(operand.length()>2){
            if(operand.substring(0, 2).contentEquals("*+")){
                int value = processStarPlusNumber(op_code, operand.substring(2));
                if(value!=0){
                    return value;
                }
                return processStarPlusLabel(op_code, operand.substring(2));
            }
            if(operand.substring(0, 2).contentEquals("*-")){
                int value = processStarMinusNumber(op_code, operand.substring(2));
                if(value!=0){
                    return value;
                }
                return processStarMinusLabel(op_code, operand.substring(2));
            }
        }
        /////////
        int value = check_instance.isValidLabel(operand);
        if(value==0){//syntactically incorrect
            if(table_instance.addToErrorTable("156")==0){
                return 1000;//fatal error more than 3072 errors
            }
            if(table_instance.addToIntermediateFile("11000", "00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }else if(value==2){//in table
            String lc = table_instance.getLcOfLabel(operand);
            if(lc.contentEquals("-100")){
                if(check_instance.isExternalLabel(operand)==1){
                    if(table_instance.addToIntermediateFile(op_code, "0<<"+operand+">>", "E") == 0){
                       return 2000;//fatal error more than 1024 memory words
                    }
                }else if(table_instance.addToIntermediateFile("11000", "0<<"+operand+">>", "RE") == 0){
                   return 2000;//fatal error more than 1024 memory words
                }
                return 50;
            }
            String bitcode = convert_instance.getBitCode(String.valueOf(Integer.parseInt(lc,16)),11);
            if(table_instance.addToIntermediateFile(op_code, bitcode, "R") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }else{//valid
            if(table_instance.addToIntermediateFile(op_code, "<<"+operand+">>", "RE") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }               
    }
            
    /**
     * The purpose of this function is to process any addition star addressing.  It will check the addition will not cause the memory to go out of range.  
     * If it is not, it will add the code to the intermediate file and return a success message.
     * <p>
     * <b>Change Log:</b><br>
     * 04-28-08 - Initial Code - Yogesh Jindal<br>   
     * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
     * 5-5-08 - Revised Documentation - Keith Hill<br>
     * <p>
     * <b>Error Conditions Tested:</b><br>
     * 116 - Memory out of range. Moper add,0 substituted.<br>
     * <p>
     * <b>Date of module being installed:</b> 04-28-08
     * <p><b>Original Author:</b>  Yogesh Jindal
     * @param op_code This is the op_code for the function being used.
     * @param operand This is the operand that will be processed.
     * @return 1000 is returned if the memory is out of range.  2000 is returned if it violates a memory parameter.  50 is returned if it was performed successfully.
     */
    protected int processStarPlusNumber(String op_code, String operand){
        if(check_instance.isInt(operand)==0){
            return 0;
        }
        if(check_instance.isParameterOverflow(operand, "nmax")==1){
            if(table_instance.addToErrorTable("116")==0){
                return 1000;
            }
            if(table_instance.addToIntermediateFile("11000","00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words.
            }
            return 50;
        }
        int operand_value = control_instance.location_counter+Integer.parseInt(operand);
        if(operand_value>1023){
            if(table_instance.addToErrorTable("116")==0){
                return 1000;
            }
            if(table_instance.addToIntermediateFile("11000","00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words.
            }
            return 50;
        }
        String bit_code = convert_instance.getBitCode(String.valueOf(operand_value),11);
        if(table_instance.addToIntermediateFile(op_code,bit_code, "R") == 0){
           return 2000;//fatal error more than 1024 memory words.
        }
        return 50;
    }
    
    /**
     * The purpose of this function is to process any addition star addressing with a label in the operand field.  
     * It will either return a failure message and load an error in the error table or it will add an item to the intermediate file and return a success message. 
     * <p>
     * <b>Change Log:</b><br>
     * 04-28-08 - Initial Code - Yogesh Jindal<br>   
     * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
     * 5-5-08 - Revised Documentation - Keith Hill<br>
     * <p>
     * <b>Error Conditions Tested:</b><br>
     * 156 - Not a valid operand. Moper add,0 replaced. <br>
     * 116 - Memory out of range. Moper add,0 substituted.<br>
     * 
     * <p>
     * <b>Date of module being installed:</b> 04-28-08
     * <p><b>Original Author:</b>  Yogesh Jindal
     * @param op_code This is the op_code for the function being used.
     * @param operand This is the operand that will be processed.
     * @return 1000 is returned if the memory is out of range.  2000 is returned if it violates a memory parameter.  50 is returned if it was performed successfully.
     */
    protected int processStarPlusLabel(String op_code, String operand){
        int value = check_instance.isValidLabel(operand);
        if(value==0){//syntactically incorrect
            if(table_instance.addToErrorTable("156")==0){
                return 1000;//fatal error more than 3072 errors
            }
            if(table_instance.addToIntermediateFile("11000", "00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }else if(value==2){//in table
            String lc = table_instance.getLcOfLabel(operand);
            if(lc.contentEquals("-100")){
                if(table_instance.addToIntermediateFile("11000", "0<<*+"+operand+">>", "RE") == 0){
                   return 2000;//fatal error more than 1024 memory words
                }
                return 50;
            }
            int lc_int = Integer.parseInt(lc,16);
            int operand_value = control_instance.location_counter+lc_int;
            if(operand_value>1023){
                if(table_instance.addToErrorTable("116")==0){
                    return 1000;
                }
                if(table_instance.addToIntermediateFile("11000","00000000000", "A") == 0){
                   return 2000;//fatal error more than 1024 memory words.
                }
                return 50;
            }
            String bit_code = convert_instance.getBitCode(String.valueOf(operand_value),11);
            if(table_instance.addToIntermediateFile(op_code,bit_code, "R") == 0){
               return 2000;//fatal error more than 1024 memory words.
            }
            return 50;
        }else{//valid
            if(table_instance.addToIntermediateFile("11000", "0<<*+"+operand+">>", "RE") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }        
    }
    
    /**
     * The purpose of this function is to process any subtraction star addressing with a number in the operand field.  It will check the addition will not cause the memory to go out of range.  
     * If it is not, it will add the code to the intermediate file and return a success message.
     * <p>
     * <b>Change Log:</b><br>
     * 04-28-08 - Initial Code - Yogesh Jindal<br>   
     * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
     * 5-5-08 - Revised Documentation - Keith Hill<br>
     * <p>
     * <b>Error Conditions Tested:</b><br>
     * 116 - Memory out of range. Moper add,0 substituted.<br>
     * <p>
     * <b>Date of module being installed:</b> 04-28-08
     * <p><b>Original Author:</b>  Yogesh Jindal
     * @param op_code This is the op_code for the function being used.
     * @param operand This is the operand that will be processed.
     * @return 1000 is returned if the memory is out of range.  2000 is returned if it violates a memory parameter.  50 is returned if it was performed successfully.
     */
    protected int processStarMinusNumber(String op_code, String operand){
        if(check_instance.isInt(operand)==0){
            return 0;
        }
        if(check_instance.isParameterOverflow(operand, "nmax")==1){
            if(table_instance.addToErrorTable("116")==0){
                return 1000;
            }
            if(table_instance.addToIntermediateFile("11000","00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words.                
            }
            return 50;
        }
        int operand_value = control_instance.location_counter-Integer.parseInt(operand);
        if(operand_value<0){
            if(table_instance.addToErrorTable("116")==0){
                return 1000;
            }
            if(table_instance.addToIntermediateFile("11000","00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words.                
            }
            return 50;
        }
        String bit_code = convert_instance.getBitCode(String.valueOf(operand_value),11);
        if(table_instance.addToIntermediateFile(op_code,bit_code, "R") == 0){
           return 2000;//fatal error more than 1024 memory words.                
        }
        return 50;        
    }
    
    /**
     * The purpose of this function is to process any subtraction star addressing with a label in the operand field.  
     * It will either return a failure message and load an error in the error table or it will add an item to the intermediate file and return a success message. 
     * <p>
     * <b>Change Log:</b><br>
     * 04-28-08 - Initial Code - Yogesh Jindal<br>   
     * 04-28-08 - Revised Documentation - Yogesh Jindal<br>
     * 5-5-08 - Revised Documentation - Keith Hill<br>
     * <p>
     * <b>Error Conditions Tested:</b><br>
     * 156 - Not a valid operand. Moper add,0 replaced. <br>
     * 116 - Memory out of range. Moper add,0 substituted.<br>
     * 
     * <p>
     * <b>Date of module being installed:</b> 04-28-08
     * <p><b>Original Author:</b>  Yogesh Jindal
     * @param op_code This is the op_code for the function being used.
     * @param operand This is the operand that will be processed.
     * @return 1000 is returned if the memory is out of range.  2000 is returned if it violates a memory parameter.  50 is returned if it was performed successfully.
     */
    protected int processStarMinusLabel(String op_code, String operand){
        int value = check_instance.isValidLabel(operand);
        if(value==0){//syntactically incorrect
            if(table_instance.addToErrorTable("156")==0){
                return 1000;//fatal error more than 3072 errors
            }
            if(table_instance.addToIntermediateFile("11000", "00000000000", "A") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }else if(value==2){//in table
            String lc = table_instance.getLcOfLabel(operand);
            int lc_int = Integer.parseInt(lc,16);
            int operand_value = control_instance.location_counter-lc_int;
            if(operand_value<0){
                if(table_instance.addToErrorTable("116")==0){
                    return 1000;
                }
                if(table_instance.addToIntermediateFile("11000","00000000000", "A") == 0){
                   return 2000;//fatal error more than 1024 memory words.                
                }
                return 50;
            }
            String bit_code = convert_instance.getBitCode(String.valueOf(operand_value),11);
            if(table_instance.addToIntermediateFile(op_code,bit_code, "A") == 0){
               return 2000;//fatal error more than 1024 memory words.                
            }
            return 50;            
        }else{//valid
            if(table_instance.addToIntermediateFile("11000", "<<*-"+operand+">>", "RE") == 0){
               return 2000;//fatal error more than 1024 memory words
            }
            return 50;
        }        
    }
                
    /**
     * This function is used to process comp instruction. This function solves the comp entirely.<p>
     * Modified Log:<br>
     * 5/10/08 - Inserted documentation - Keith Hill<br>
     * <p>
     * Error Condition tested:<p>
     * None.<br>
     * <p>
     * Creation Date : May 6,2008.<br>
     * <p>
     * <b>Original Author:</b> Yogesh Jindal.<br>    
     * @param label The label in the comp field
     * @param operand The operand expression of comp
     * @return Returns an integer value that tells how to proceed to next line. It the returned integer
     * corresponds to an integer then the program exits else the program proceeds to next line.
     */
    protected int processComp(String label, String operand){        
        Comp.Evaluate comp_evaluate_instance = new Comp.Evaluate();
        String[] broken_array = comp_evaluate_instance.breakComp(operand);        
        if(broken_array[0].contentEquals("wrong expression")){
            System.out.println("wrong expression");//ignore the instruction..and return 50.
            if(table_instance.addToErrorTable("162")==0){
                return 1000;//fatal error more than 3072 errors
            }
            return 50;
        }else{
            if(table_instance.addToSymbolTable(label,"COMP", "-") == 0){
                return 2000;//fatal error more than 1024 memory words.                
            }
            Tokenize tokenize_instance = new Tokenize();
            Process process_instance = new Process();
            for(int index=0; index<broken_array.length; index++){            
                String[] tokened_string = tokenize_instance.tokenize(broken_array[index]);
                int ret_value=process_instance.processInstruction(tokened_string);
                if(ret_value==1000){
                    return 1000;
                }else if(ret_value==2000){
                    return 2000;
                }else if(ret_value==50){
                    
                }else if(ret_value==4000){
                    return 4000;
                }
            }
        }
        return 0;
    }
}
